home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 6366 / 6366.xpi / components / xdGestureMapping.js < prev    next >
Text File  |  2009-11-17  |  10KB  |  319 lines

  1.  
  2. const Cc = Components.classes;
  3. const Ci = Components.interfaces;
  4. const Cr = Components.results;
  5. const Cu = Components.utils;
  6.  
  7. const TYPE_CATEGORY = Ci.xdIGestureMapping.TYPE_CATEGORY;
  8. const TYPE_NORMAL   = Ci.xdIGestureMapping.TYPE_NORMAL;
  9. const TYPE_SCRIPT   = Ci.xdIGestureMapping.TYPE_SCRIPT;
  10.  
  11. const RDF_NS   = "http://www.xuldev.org/firegestures-mapping#";
  12. const RDF_ROOT = "urn:mapping:root";
  13. const BROWSER_ID = "gesture_mappings";
  14. const WINDOW_TYPE = "FireGestures:Options";
  15.  
  16. Cu.import("resource://gre/modules/XPCOMUtils.jsm");
  17.  
  18.  
  19.  
  20. function alert(aMsg) {
  21.     Cu.reportError(aMsg);
  22.     var fuelApp = Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication);
  23.     fuelApp.console.open();
  24. }
  25.  
  26.  
  27.  
  28. function xdGestureMapping() {}
  29.  
  30.  
  31. xdGestureMapping.prototype = {
  32.  
  33.  
  34.     classDescription: "Mouse Gesture Mapping",
  35.     contractID: "@xuldev.org/firegestures/mapping;1",
  36.     classID: Components.ID("{d7018e80-d6da-4cbc-b77f-8dca4d95bbbf}"),
  37.     QueryInterface: XPCOMUtils.generateQI([
  38.         Ci.nsISupports,
  39.         Ci.xdIGestureMapping
  40.     ]),
  41.  
  42.  
  43.  
  44.     get rdfSvc() {
  45.         if (!this._rdfSvc)
  46.             this._rdfSvc = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
  47.         return this._rdfSvc;
  48.     },
  49.     _rdfSvc: null,
  50.  
  51.  
  52.  
  53.     id: null,
  54.  
  55.     name: null,
  56.  
  57.     _dataSource: null,
  58.  
  59.     _mapping: null,
  60.  
  61.     _getDBConnection: null,
  62.  
  63.  
  64.  
  65.  
  66.     init: function FGM_init(aID, aURI, aName) {
  67.         if (this._dataSource)
  68.             throw Cr.NS_ERROR_ALREADY_INITIALIZED;
  69.         if (!/^\w+$/.test(aID))
  70.             throw Cr.NS_ERROR_ILLEGAL_VALUE;
  71.         this.id = aID;
  72.         this.name = aName;
  73.         var gestureSvc = Cc["@xuldev.org/firegestures/service;1"].getService(Ci.xdIGestureService);
  74.         this._getDBConnection = gestureSvc.getDBConnection;
  75.         try {
  76.             this._dataSource = this.rdfSvc.GetDataSourceBlocking(aURI);
  77.         }
  78.         catch(ex) {
  79.             alert("FireGestures: An error occurred while parsing gesture mapping.\n\n" + ex);
  80.             throw ex;
  81.         }
  82.         this._reloadMapping();
  83.     },
  84.  
  85.     _ensureInit: function FGM__ensureInit() {
  86.         if (!this._dataSource)
  87.             throw Cr.NS_ERROR_NOT_INITIALIZED;
  88.     },
  89.  
  90.     finalize: function FGM_finalize() {
  91.         if (this._dataSource)
  92.             this.rdfSvc.UnregisterDataSource(this._dataSource);
  93.         this.id   = null;
  94.         this.name = null;
  95.         this._dataSource = null;
  96.         this._mapping    = null;
  97.     },
  98.  
  99.     _reloadMapping: function FGM__reloadMapping() {
  100.         this._mapping = null;
  101.         this._getUserMapping() || this._getDefaultMapping();
  102.     },
  103.  
  104.     _getUserMapping: function FGM__getUserMapping() {
  105.         this._ensureInit();
  106.         var dbConn = this._getDBConnection(false);
  107.         if (!dbConn || !dbConn.tableExists(this.id))
  108.             return false;
  109.         this._mapping = {};
  110.         var stmt = dbConn.createStatement("SELECT * FROM " + this.id);
  111.         try {
  112.             while (stmt.executeStep()) {
  113.                 var type      = stmt.getInt32(0);
  114.                 var name      = stmt.getUTF8String(1);
  115.                 var command   = stmt.getUTF8String(2);
  116.                 var direction = stmt.getUTF8String(3);
  117.                 if (!command || !direction)
  118.                     continue;
  119.                 if (type != TYPE_SCRIPT)
  120.                     name = this._getLocalizedNameForCommand(command);
  121.                 this._mapping[direction] = new xdGestureCommand(type, name, command);
  122.             }
  123.         }
  124.         catch(ex) { Cu.reportError(ex); }
  125.         finally { stmt.reset(); stmt.finalize(); }
  126.         return true;
  127.     },
  128.  
  129.     _getDefaultMapping: function FGM__getDefaultMapping() {
  130.         this._ensureInit();
  131.         this._mapping = {};
  132.         var rdfCont = Cc["@mozilla.org/rdf/container;1"].createInstance(Ci.nsIRDFContainer);
  133.         rdfCont.Init(this._dataSource, this.rdfSvc.GetResource(RDF_ROOT));
  134.         var resEnum = rdfCont.GetElements();
  135.         while (resEnum.hasMoreElements()) {
  136.             var res = resEnum.getNext().QueryInterface(Ci.nsIRDFResource);
  137.             var type      = parseInt(this._getPropertyValue(res, "type"), 10);
  138.             var name      = this._getPropertyValue(res, "name");
  139.             var command   = res.Value.substr(("urn:").length);
  140.             var direction = this._getPropertyValue(res, "direction");
  141.             var extra     = this._getPropertyValue(res, "extra");
  142.             if (type == TYPE_CATEGORY || (!direction && !extra))
  143.                 continue;
  144.             this._mapping[direction] = new xdGestureCommand(type, name, command);
  145.             if (extra)
  146.                 this._mapping[extra] = new xdGestureCommand(type, name, command);
  147.         }
  148.     },
  149.  
  150.     _getLocalizedNameForCommand: function FGM__getLocalizedNameForCommand(aCommand) {
  151.         var res = this.rdfSvc.GetResource("urn:" + aCommand);
  152.         return this._getPropertyValue(res, "name");
  153.     },
  154.  
  155.     _getPropertyValue: function FGM__getPropertyValue(aRes, aProp) {
  156.         aProp = this.rdfSvc.GetResource(RDF_NS + aProp);
  157.         try {
  158.             var target = this._dataSource.GetTarget(aRes, aProp, true);
  159.             return target ? target.QueryInterface(Ci.nsIRDFLiteral).Value : null;
  160.         }
  161.         catch(ex) {
  162.             return null;
  163.         }
  164.     },
  165.  
  166.  
  167.     getCommandForDirection: function FGM_getCommandForDirection(aDirection) {
  168.         return this._mapping[aDirection];
  169.     },
  170.  
  171.     configure: function FGS_configure() {
  172.         var browser = this.id == BROWSER_ID;
  173.         var type = browser ? WINDOW_TYPE : WINDOW_TYPE + ":" + this.id;
  174.         var winMed = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
  175.         var win = winMed.getMostRecentWindow(type);
  176.         if (win) {
  177.             win.focus();
  178.             win.document.documentElement.showPane(win.document.getElementById("mappingPane"));
  179.             return;
  180.         }
  181.         var url = browser ? "chrome://firegestures/content/prefs.xul" : 
  182.                             "chrome://firegestures/content/prefs-generic.xul";
  183.         var features = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
  184.         win = winMed.getMostRecentWindow(null);
  185.         if (browser)
  186.             win.openDialog(url, type, features);
  187.         else
  188.             win.openDialog(url, type, features, this.id);
  189.     },
  190.  
  191.     getMappingArray: function FGM_getMappingArray() {
  192.         this._ensureInit();
  193.         var items = [];
  194.         var dbConn = this._getDBConnection(false);
  195.         if (!dbConn || !dbConn.tableExists(this.id))
  196.             dbConn = null;
  197.         var rdfCont = Cc["@mozilla.org/rdf/container;1"].createInstance(Ci.nsIRDFContainer);
  198.         rdfCont.Init(this._dataSource, this.rdfSvc.GetResource(RDF_ROOT));
  199.         var resEnum = rdfCont.GetElements();
  200.         while (resEnum.hasMoreElements()) {
  201.             var res = resEnum.getNext().QueryInterface(Ci.nsIRDFResource);
  202.             var type    = parseInt(this._getPropertyValue(res, "type"), 10);
  203.             var name    = this._getPropertyValue(res, "name");
  204.             var command = res.Value.substr("urn:".length);
  205.             var flags   = this._getPropertyValue(res, "flags");
  206.             if (dbConn && type == TYPE_NORMAL) {
  207.                 var directions = [];
  208.                 var stmt = dbConn.createStatement("SELECT direction FROM " + this.id + " WHERE command = ?");
  209.                 stmt.bindUTF8StringParameter(0, command);
  210.                 try {
  211.                     while (stmt.executeStep())
  212.                         directions.push(stmt.getUTF8String(0));
  213.                 }
  214.                 catch(ex) { Cu.reportError(ex); }
  215.                 finally { stmt.reset(); stmt.finalize(); }
  216.                 if (!directions.some(function(direction) { return /^[LRUD]*$/.test(direction); }))
  217.                     directions.unshift("");
  218.                 for each (var direction in directions)
  219.                     items.push([type, name, command, direction, flags]);
  220.             }
  221.             else {
  222.                 var direction = this._getPropertyValue(res, "direction") || "";
  223.                 var extra     = this._getPropertyValue(res, "extra");
  224.                 items.push([type, name, command, direction, flags]);
  225.                 if (extra)
  226.                     items.push([type, name, command, extra, flags]);
  227.             }
  228.         }
  229.         if (dbConn) {
  230.             var sql = "SELECT name, command, direction FROM " + this.id + " WHERE type = " + TYPE_SCRIPT;
  231.             var stmt = dbConn.createStatement(sql);
  232.             try {
  233.                 while (stmt.executeStep()) {
  234.                     items.push([
  235.                         TYPE_SCRIPT, stmt.getUTF8String(0), stmt.getUTF8String(1), stmt.getUTF8String(2), null
  236.                     ]);
  237.                 }
  238.             }
  239.             catch(ex) { Cu.reportError(ex); }
  240.             finally { stmt.reset(); stmt.finalize(); }
  241.         }
  242.         return items;
  243.     },
  244.  
  245.     saveUserMapping: function FGM_saveUserMapping(aItems) {
  246.         this._ensureInit();
  247.         var dbConn = this._getDBConnection(true);
  248.         dbConn.executeSimpleSQL("DROP TABLE IF EXISTS " + this.id);
  249.         dbConn.createTable(this.id, "type INTEGER, name TEXT, command TEXT, direction TEXT");
  250.         dbConn.beginTransaction();
  251.         for each (let [type, name, command, direction] in aItems) {
  252.             if (type == TYPE_CATEGORY || (type == TYPE_NORMAL && (!direction || !command)))
  253.                 continue;
  254.             var stmt = dbConn.createStatement("INSERT INTO " + this.id + " VALUES(?,?,?,?)");
  255.             stmt.bindInt32Parameter(0, type);
  256.             stmt.bindUTF8StringParameter(1, type == TYPE_SCRIPT ? name : "");
  257.             stmt.bindUTF8StringParameter(2, command);
  258.             stmt.bindUTF8StringParameter(3, direction);
  259.             try {
  260.                 stmt.execute();
  261.             }
  262.             catch(ex) { Cu.reportError(ex); }
  263.             finally { stmt.reset(); stmt.finalize(); }
  264.         }
  265.         dbConn.commitTransaction();
  266.         this._reloadMapping();
  267.     },
  268.  
  269.     addScriptCommands: function FGM_addScriptCommands(aItems) {
  270.         this._ensureInit();
  271.         var added = false;
  272.         var items = this.getMappingArray();
  273.         outer: for each (let aItem in aItems) {
  274.             if (this.getCommandForDirection(aItem.direction))
  275.                 aItem.direction = "";
  276.             inner: for each (let [ type, , script, ] in items) {
  277.                 if (type != TYPE_SCRIPT)
  278.                     continue inner;
  279.                 if (script == aItem.script)
  280.                     continue outer;
  281.             }
  282.             items.push([TYPE_SCRIPT, aItem.name, aItem.script, aItem.direction, null]);
  283.             added = true;
  284.         }
  285.         if (!added)
  286.             return;
  287.         this.saveUserMapping(items);
  288.         this._reloadMapping();
  289.     },
  290.  
  291. };
  292.  
  293.  
  294.  
  295. function xdGestureCommand(aType, aName, aCommand, aDirection) {
  296.     this.type = aType;
  297.     this.name = aName;
  298.     this.value = aCommand;
  299.     this.direction = aDirection;
  300. }
  301.  
  302. xdGestureCommand.prototype = {
  303.     QueryInterface: function(aIID) {
  304.         if (!aIID.equals(Ci.nsISupports) && 
  305.             !aIID.equals(Ci.xdIGestureCommand)) {
  306.             throw Cr.NS_ERROR_NO_INTERFACE;
  307.         }
  308.         return this;
  309.     }
  310. };
  311.  
  312.  
  313.  
  314. function NSGetModule(compMgr, fileSpec) {
  315.     return XPCOMUtils.generateModule([xdGestureMapping]);
  316. }
  317.  
  318.  
  319.